Maintain a hash table of live handles and check that we have no
authorMatthias Clasen <mclasen@redhat.com>
Wed, 23 Aug 2006 06:07:10 +0000 (06:07 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Wed, 23 Aug 2006 06:07:10 +0000 (06:07 +0000)
2006-08-23  Matthias Clasen  <mclasen@redhat.com>

* gtk/gtkfilesystemunix.c: Maintain a hash table
of live handles and check that we have no outstanding
handles at finalization time. (Copying what
Federico did for gtkfilesystemgnomevfs.c)

ChangeLog
gtk/gtkfilesystemunix.c

index 3323ced966b9f29e4badc42b2dcd2a97f933bac1..5c1eb9f7a234e930db820e7a2ca6f6a5f1a31b37 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-08-23  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkfilesystemunix.c: Maintain a hash table
+       of live handles and check that we have no outstanding
+       handles at finalization time. (Copying what
+       Federico did for gtkfilesystemgnomevfs.c)
+
 2006-08-22  Matthias Clasen  <mclasen@redhat.com> 
 
        * Branch for 2.10
index 73be26a9ef3e031ecf031e0f4690bf4051972996..1a6ed04b8c2ba077b266bbe8b7c05a049071d7da 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+/* #define this if you want the program to crash when a file system gets
+ * finalized while async handles are still outstanding.
+ */
+#undef HANDLE_ME_HARDER
+
 #include <config.h>
 
 #include "gtkfilesystem.h"
@@ -68,6 +73,8 @@ struct _GtkFileSystemUnix
   struct stat afs_statbuf;
   struct stat net_statbuf;
 
+  GHashTable *handles;
+
   guint have_afs : 1;
   guint have_net : 1;
 };
@@ -339,8 +346,80 @@ gtk_file_system_unix_init (GtkFileSystemUnix *system_unix)
     system_unix->have_net = TRUE;
   else
     system_unix->have_net = FALSE;
+
+  system_unix->handles = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+static void
+check_handle_fn (gpointer key, gpointer value, gpointer data)
+{
+  GtkFileSystemHandle *handle;
+  int *num_live_handles;
+
+  handle = key;
+  num_live_handles = data;
+
+  (*num_live_handles)++;
+
+  g_warning ("file_system_unix=%p still has handle=%p at finalization which is %s!",
+            handle->file_system,
+            handle,
+            handle->cancelled ? "CANCELLED" : "NOT CANCELLED");
+}
+
+static void
+check_handles_at_finalization (GtkFileSystemUnix *system_unix)
+{
+  int num_live_handles;
+
+  num_live_handles = 0;
+
+  g_hash_table_foreach (system_unix->handles, check_handle_fn, &num_live_handles);
+#ifdef HANDLE_ME_HARDER
+  g_assert (num_live_handles == 0);
+#endif
+
+  g_hash_table_destroy (system_unix->handles);
+}
+
+#define GTK_TYPE_FILE_SYSTEM_HANDLE_UNIX (_gtk_file_system_handle_unix_get_type ())
+
+typedef struct _GtkFileSystemHandle GtkFileSystemHandleUnix;
+typedef struct _GtkFileSystemHandleClass GtkFileSystemHandleUnixClass;
+
+G_DEFINE_TYPE (GtkFileSystemHandleUnix, _gtk_file_system_handle_unix, GTK_TYPE_FILE_SYSTEM_HANDLE)
+
+static void
+_gtk_file_system_handle_unix_init (GtkFileSystemHandleUnix *handle)
+{
+}
+
+static void 
+_gtk_file_system_handle_unix_finalize (GObject *object)
+{
+  GtkFileSystemHandleUnix *handle;
+  GtkFileSystemUnix *system_unix;
+
+  handle = (GtkFileSystemHandleUnix *)object;
+
+  system_unix = GTK_FILE_SYSTEM_UNIX (GTK_FILE_SYSTEM_HANDLE (handle)->file_system);
+
+  g_assert (g_hash_table_lookup (system_unix->handles, handle) != NULL);
+  g_hash_table_remove (system_unix->handles, handle);
+
+  if (G_OBJECT_CLASS (_gtk_file_system_handle_unix_parent_class)->finalize)
+    G_OBJECT_CLASS (_gtk_file_system_handle_unix_parent_class)->finalize (object);
 }
 
+static void
+_gtk_file_system_handle_unix_class_init (GtkFileSystemHandleUnixClass *class)
+{
+  GObjectClass *gobject_class = (GObjectClass *) class;
+
+  gobject_class->finalize = _gtk_file_system_handle_unix_finalize;
+}
+
+
 static void
 gtk_file_system_unix_finalize (GObject *object)
 {
@@ -348,6 +427,8 @@ gtk_file_system_unix_finalize (GObject *object)
 
   system_unix = GTK_FILE_SYSTEM_UNIX (object);
 
+  check_handles_at_finalization  (system_unix);
+
   /* FIXME: assert that the hash is empty? */
   g_hash_table_destroy (system_unix->folder_hash);
 
@@ -670,11 +751,17 @@ queue_callback (enum callback_types type, gpointer data)
 static GtkFileSystemHandle *
 create_handle (GtkFileSystem *file_system)
 {
+  GtkFileSystemUnix *system_unix;
   GtkFileSystemHandle *handle;
 
-  handle = g_object_new (GTK_TYPE_FILE_SYSTEM_HANDLE, NULL);
+  system_unix = GTK_FILE_SYSTEM_UNIX (file_system);
+
+  handle = g_object_new (GTK_TYPE_FILE_SYSTEM_HANDLE_UNIX, NULL);
   handle->file_system = file_system;
 
+  g_assert (g_hash_table_lookup (system_unix->handles, handle) == NULL);
+  g_hash_table_insert (system_unix->handles, handle, handle);
+
   return handle;
 }